package cn.niu.ts;

import org.apache.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TsPackage {

    int sequence = 0;

    /**
     * 获取一个ts文件
     *
     * @param list
     * @return
     * @throws IOException
     */
    public static byte[] getTs(List<byte[]> list) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        outputStream.write(getPat());
        outputStream.write(getPmt());

        for (byte[] buf : list) {
            outputStream.write(buf);
        }

        return outputStream.toByteArray();
    }

    Logger logger = Logger.getLogger("TsPackage");

    /**
     * 获取音频ts
     *
     * @param buf
     * @return
     */
    public List<byte[]> getAudioTs(byte[] buf, long pts) throws IOException {

        List<byte[]> list = new ArrayList<>();
        int len = 0;
        byte[] pes = PesPackage.getPes(buf, pts);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        //写入文件头
        writeHeader(byteArrayOutputStream, 0x41, 0x01, 0x10 + addSequence());
        //写入数据
        byteArrayOutputStream.write(pes, 0, 184);
        len = 184;

        list.add(byteArrayOutputStream.toByteArray());
        byteArrayOutputStream.reset();

        while (len < pes.length) {
            int left = pes.length - len;
            if (left >= 184) {
                writeHeader(byteArrayOutputStream, 0x01, 0x01, 0x10 + addSequence());
                byteArrayOutputStream.write(pes, len, 184);
            } else if (left == 183) {
                //长度为183时
                writeHeader(byteArrayOutputStream, 0x01, 0x01, 0x30 + addSequence());
                byteArrayOutputStream.write(0);
                byteArrayOutputStream.write(pes, len, 183);
            } else {
                writeHeader(byteArrayOutputStream, 0x01, 0x01, 0x30 + addSequence());
                //填充 0xff数量
                int fillSize = 183 - left;
                byteArrayOutputStream.write(fillSize);
                //填充一个 0
                byteArrayOutputStream.write(0);

                for (int i = 1; i < fillSize; i++) {
                    byteArrayOutputStream.write(0xFF);
                }

                byteArrayOutputStream.write(pes, len, left);
            }
            len += 184;
            list.add(byteArrayOutputStream.toByteArray());
            byteArrayOutputStream.reset();
        }

        return list;
//        return byteArrayOutputStream.toByteArray();
    }

    private static byte[] pmt;
    private static byte[] pat;

    /**
     * 获取pmt
     *
     * @return
     */
    public static byte[] getPmt() {

        if (pmt == null) {
            synchronized (TsPackage.class) {
                if (pmt == null) {
                    pmt = new byte[188];
                    //47 50 01 10 00 02 B0 17 00 01 C1 00 00 E1 00 F0 00 1B E1 00 F0 00 0F E1 01 F0 00 2F 44 B9 9B
                    //47 50 01 10 00 02 B0 17 00 01 C1 00 00 E1 00 F0 00 0F E1 01 F0 00 13 30 2E 3D
                    //pmt和pat使用固定值
                    String str = "47 50 01 10 00 02 B0 17 00 01 C1 00 00 E1 00 F0 00 1B E1 00 F0 00 0F E1 01 F0 00 2F 44 B9 9B"
                            .replaceAll(" ", "");

                    byte[] pmtHeader = ByteUtil.hexStringToByteArray(str);
                    for (int i = 0; i < pmtHeader.length; i++) {
                        pmt[i] = pmtHeader[i];
                    }
                    for (int i = pmtHeader.length; i < pmt.length; i++) {
                        pmt[i] = (byte) 0xff;
                    }
                }
            }
        }

        return pmt;

    }

    /**
     * 获取pat
     *
     * @return
     */
    public static byte[] getPat() {
        if (pat == null) {
            synchronized (TsPackage.class) {
                if (pat == null) {
                    pat = new byte[188];
                    //47 40 00 10 00 00 B0 0D 00 01 C1 00 00 00 01 F0 01 2E 70 19 05
                    //pmt和pat使用固定值
                    String str = "47 40 00 10 00 00 B0 0D 00 01 C1 00 00 00 01 F0 01 2E 70 19 05"
                            .replaceAll(" ", "");

                    byte[] pmtHeader = ByteUtil.hexStringToByteArray(str);
                    for (int i = 0; i < pmtHeader.length; i++) {
                        pat[i] = pmtHeader[i];
                    }
                    for (int i = pmtHeader.length; i < pat.length; i++) {
                        pat[i] = (byte) 0xff;
                    }
                }
            }
        }

        return pat;
    }

    private static void writeHeader(ByteArrayOutputStream outputStream, int byte2, int byte3, int byte4) {
        outputStream.write(0x47);
        outputStream.write(byte2);
        outputStream.write(byte3);
        outputStream.write(byte4);
    }

    public int addSequence() {
        sequence = (sequence + 1) % 16;
        return sequence;
    }
}
